import annotation.Controller;
import annotation.RequestMapping;
import singletonpattern.Singleton;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @ClassName Main
 * @Description : 反射练习Main类
 * @Author : R
 * @Date : 2020/3/5 9:34
*/
public class Main {
    public static void testMain(Class aClass,String path) throws InvocationTargetException, IllegalAccessException, InstantiationException {
         Annotation annotation = aClass.getAnnotation(Controller.class);
        if (annotation != null){
            final Object o = aClass.newInstance();
            final Method[] declaredMethods1 = o.getClass().getDeclaredMethods();
                for (Method method : declaredMethods1) {
                    final RequestMapping annotation1 = method.getAnnotation(RequestMapping.class);
                    final String value = annotation1.value();
                    if (path.equals(value)){
                        final Object invoke = method.invoke(o);
                        System.out.println("invoke====="+invoke);
                    }
                }
        }
    }
    //通过loader加载所有类
    private static List<Class> loadClassByLoader(ClassLoader load) throws Exception{
        Enumeration<URL> urls = load.getResources("");
        //放所有类型
        List<Class> classes = new ArrayList<Class>();
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            //文件类型（其实是文件夹）
            if (url.getProtocol().equals("file")) {
                loadClassByPath(null, url.getPath(), classes, load);
            }
        }
        return classes;
    }
    //通过文件路径加载所有类 root 主要用来替换path中前缀（除包路径以外的路径）
    private static void loadClassByPath(String root, String path, List<Class> list, ClassLoader load) {
        File f = new File(path);
        if(root==null){
            root = f.getPath();
        }
        //判断是否是class文件
        if (f.isFile() && f.getName().matches("^.*\\.class$")) {
            try {
                String classPath = f.getPath();
                //截取出className 将路径分割符替换为.（windows是\ linux、mac是/）
                String className = classPath.substring(root.length()+1,classPath.length()-6).replace('/','.').replace('\\','.');
                list.add(load.loadClass(className));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        } else {
            File[] fs = f.listFiles();
            if (fs == null){
                return;
            }
            for (File file : fs) {
                loadClassByPath(root,file.getPath(), list, load);
            }
        }
    }
    public static void main(String[] args) throws Exception {
        /**
         * 单例模式测试
         */
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
        for (int i = 0; i < 100; i++) {
            fixedThreadPool.submit(()->{
                Singleton.getSingleton();
            });
            fixedThreadPool.submit(()->{
                Singleton.getSingleton();
            });
            new Thread(()->{
                Singleton.getSingleton();
            }).start();
        }
        fixedThreadPool.shutdown();

        /**
         * java反射 注解问题
         */
        Main main = new Main();
        List<Class> classes = loadClassByLoader(main.getClass().getClassLoader());
        while(true){
            Scanner scan = new Scanner(System.in);
            System.err.println("请输入方法名(输入0结束程序运行):");
            String line = scan.nextLine();
            for (Class aClass : classes) {
                testMain(aClass,line);
                String index = "0";
                while(index.equals(line))
                {
                    return;
                }
            }
        }
    }
}